home *** CD-ROM | disk | FTP | other *** search
/ FishMarket 1.0 / FishMarket v1.0.iso / fishies / 051-075 / disk_065 / prep / prep.c < prev    next >
C/C++ Source or Header  |  1992-05-06  |  6KB  |  222 lines

  1. /* Program PREP.C
  2.  *
  3.  * Preprocessor for FORTRAN 77.
  4.  * Adds the additional features:
  5.  *
  6.  *  1) Vector arithmetic:
  7.  *     a(#,#,1) = b(#,#) + 1
  8.  *
  9.  *   [ a(#) = b(#)*c(#) - 100
  10.  *     x = y
  11.  *     d(#) = e(#)         ]
  12.  *
  13.  *  2) Case construct:
  14.  *     case ( exp1 )
  15.  *     of   ( exp2 )  line of code
  16.  *                    line of code
  17.  *                    continue_case
  18.  *     of   ( exp3 )  line of code
  19.  *     default        line of code
  20.  *                    line of code
  21.  *     end_case
  22.  *
  23.  *  3) do i = 1, 10
  24.  *        line of code
  25.  *        line of code
  26.  *     leave_do (optional expression)
  27.  *        line of code
  28.  *     continue_do (optional expression)
  29.  *        line of code
  30.  *     end_do
  31.  *
  32.  *  4) forth style begin/while/until/again construct:
  33.  *     begin ... again
  34.  *     begin ... while (exp1) ... again
  35.  *     begin ... until (exp1)
  36.  *     leave (optional expression) to exit current level
  37.  *     continue (optional expression) to go back to beginning
  38.  *
  39.  *  5) Vector loop unrolling to any depth, for loops 
  40.  *     that can be expressed as in #1 above.
  41.  *
  42.  *  6) Macro processing, define a macro "name" with:
  43.  *     : name(a,b,c)    a = a + func( c, d ) ;
  44.  *
  45.  *  7) Included files:
  46.  *     #include "filename"
  47.  *
  48.  *  8) Conditional compilation:
  49.  *     #ifdef, #ifndef, #else, #endif
  50.  *
  51.  *    The nesting limit for all loops is defined by the constant
  52.  * NESTING in file prepdefs.h.  All underline characters are removed,
  53.  * as are comments if com_keep is NULL.
  54.  *    Any delimeters (){}[]'" may be used in the logical expressions
  55.  * ( i.e.  leave [i .eq. 1] ).
  56.  *    The flow control directives are permitted inside vector
  57.  * loops, but since they will inhibit Cray vectorization of those
  58.  * loops it may be best to avoid this.  One of the reasons for
  59.  * using the vector shorthand is that it encourages programming
  60.  * in a style that can be easily vectorized.
  61.  *    Some attempts have been made to avoid ratfor syntax to that
  62.  * both preprocessors can be used, but this has never been checked.
  63.  *    The number of parameters allowed in a macro is set by the constant
  64.  * MAX_MAC_PARMS in file prepdefs.h (20 is probably more than enough).
  65.  *    Although the syntax is similar to forth, the spirit of
  66.  * forth is totally absent.  The macros are really macros,
  67.  * not colon definitions, and recursive macro definitions will cause
  68.  * an error during expansion.  Postfix notation would only cause
  69.  * confusion, being in conflict with fortran conventions, and is
  70.  * not used.
  71.  *    The macro processor can be considered a pre-preprocessor.  The
  72.  * order of translation is:
  73.  *
  74.  *    1) file inclusion & conditional compilation
  75.  *    2) macro processing
  76.  *    3) flow control extensions
  77.  *    4) vector statements
  78.  *
  79.  * Note that because of this the flow control syntax can be modified
  80.  * at the macro level.
  81.  *
  82.  * Switches:
  83.  *   -c        keep comments (truncated at column 72)
  84.  *   -u        keep underline characters
  85.  *   -m        only do macro substitution (==> -c and -u as well, and
  86.  *        prevents file includes (except -i switch).
  87.  *   -i    <file>    include <file> before processing
  88.  *   -d <name>  define <name> as a macro, using :name 1;
  89.  *   -r n    unroll vector loops to depth n
  90.  *   -l n    unroll loops with n or fewer lines
  91.  *   -(other)    write message about allowed switches
  92.  *
  93.  * P. R. OVE  11/9/85
  94.  */
  95.  
  96. #define    MAIN    1
  97. #include "prep.h"
  98.  
  99. main( argc, argv )
  100. int    argc ;
  101. char    *argv[] ;
  102. {
  103. int     i, j, maxlength, lines ;
  104. char    *text, *semi ;
  105.  
  106.  
  107. init() ;
  108. parmer( argc, argv ) ;    /* process command line switches */
  109.  
  110. /* copyright notice */
  111. fprintf( stderr,
  112.     "PREP: Copyright P.R.Ove.\n" ) ;
  113.  
  114. /* Main loop, loop until true end of file */
  115. while ( NULL != get_rec() ) {
  116.  
  117.     /* if an #ifdef has turned off processing, keep looking for #endif.. */
  118.     if ( ignore_flag ) {
  119.         if (NULL != (semi = strchrq(in_buff,';'))) *semi = NULL ;
  120.         preproc( rec_type(0) ) ;
  121.         continue ;
  122.     }
  123.  
  124.     if ( comment_filter() ) continue ; /* TRUE ==> nothing left */
  125.  
  126.     /* if only doing macro expansion: */
  127.     if ( macro_only ) {
  128.         if ( NULL != (text = mac_proc()) ) { /* NULL ==> macro def */
  129.             put_string( text ) ;
  130.             free( text ) ;
  131.         }
  132.         continue ;
  133.     }
  134.  
  135.     /* handle file inclusion & #ifdefs */
  136.     if ( NULL == preproc(rec_type(0))) continue ;
  137.  
  138.     /* expand macros in in_buff, result pointed to by text */
  139.     if ( NULL == (text = mac_proc()) ) continue ; /* NULL ==> macro def */
  140.  
  141.     /* count lines in text, delimit with NULLs, and find the longest line */
  142.     for ( maxlength=0, i=0, j=0, lines=1;; i++, j++ ) {
  143.         if ( text[i] == '\n' ) {
  144.             text[i] = NULL ;
  145.             if ( j>maxlength ) maxlength = j ;
  146.             j = -1 ;
  147.             lines++ ;
  148.             continue ;
  149.         }
  150.         if ( text[i] == NULL ) {
  151.             if ( j>maxlength ) maxlength = j ;
  152.             break ;
  153.         }
  154.     }
  155.  
  156.     /* if necessary expand the output buffer size */
  157.     if ( maxlength > allocation ) {
  158.         allocation = maxlength + maxlength/10 ;
  159.         if ( NULL == (in_buff = realloc( in_buff, allocation )) )
  160.             abort( "reallocation failed" ) ;
  161.         if ( NULL == (out_buff = realloc( out_buff, 4*allocation )) )
  162.             abort( "reallocation failed" ) ;
  163.     }
  164.  
  165.     /* send each line through the passes */
  166.     for ( j=0, i=0; j<lines; j++, i+=strlen(&text[i])+1 ) {
  167.         strcpy( in_buff, &text[i] ) ;
  168.         passes() ;
  169.     }
  170.     
  171.     /* free the storage created by mac_proc */
  172.     free( text ) ;
  173. }
  174. fclose( out ) ;        /* SVS seems to need this explicit close */
  175. }
  176.  
  177.  
  178.  
  179. /* Do preprocessor passes 1, 2, and 3 on text in in_buff.  Output is
  180.  * also done here.
  181.  */
  182. passes()
  183. {
  184.  
  185. /* process the statement until it is NULL */
  186. while (1) {
  187.  
  188.     if ( NULL == preproc( rec_type(1) ) ) break ;
  189.  
  190.     if ( NULL == preproc( rec_type(2) ) ) break ;
  191.  
  192.     if ( NULL == preproc( rec_type(3) ) ) break ;
  193. }
  194. }
  195.  
  196.  
  197.  
  198.  
  199. /* initialization */
  200. init() {
  201.  
  202. flow_init() ;
  203. vec_init() ;
  204.  
  205. /* Allocate some space for the buffers. */
  206. allocation = DEF_BUFFSIZE ;
  207. GET_MEM( in_buff, allocation ) ;
  208. GET_MEM( out_buff, 4*allocation ) ;
  209. }
  210.  
  211.  
  212.  
  213. /* error exit */
  214. abort( string )
  215. char    *string ;
  216. {
  217.     fprintf( stderr, "%s\n", string ) ;
  218.     fprintf( out, "%s\n", string ) ;
  219.     fclose( out ) ;
  220.     exit(1) ;
  221. }
  222.